package syM

import (
	cp "db2s/componentInit"
	mq "db2s/topic-mq"
	"reflect"
	"strings"
)

func structMQListenInit(t, _ int) map[Topic]*cp.MQTopicListeners {
	return map[Topic]*cp.MQTopicListeners{
		StructIsBaseQuery:      cp.NewMQTopicListeners(cp.Topic(StructIsBaseQuery), t, singleQueryMessageQueueLength, structIsBaseQueryListeners, 5, 11),
		StructIsColumnMeta:     cp.NewMQTopicListeners(cp.Topic(StructIsColumnMeta), t, singleQueryMessageQueueLength, structIsColumnMetaQueryListeners, 5, 11),
		StructIsIndexMeta:      cp.NewMQTopicListeners(cp.Topic(StructIsIndexMeta), t, singleQueryMessageQueueLength, structIsIndexMetaQueryListeners, 5, 11),
		StructIsPartMeta:       cp.NewMQTopicListeners(cp.Topic(StructIsPartMeta), t, singleQueryMessageQueueLength, structIsPartMetaQueryListeners, 5, 11),
		StructIsMetaComparison: cp.NewMQTopicListeners(cp.Topic(StructIsMetaComparison), t, singleQueryMessageQueueLength, structIsMetaComparisonListeners, 5, 11),
		StructIsFix:            cp.NewMQTopicListeners(cp.Topic(StructIsFix), t, singleQueryMessageQueueLength, structIsFixListeners, 5, 11),
		StructIsApply:          cp.NewMQTopicListeners(cp.Topic(StructIsApply), t, singleQueryMessageQueueLength, structIsApplyListeners, 5, 11),
	}
}
func structMQListenInitFunc(t, p int) map[cp.CheckMode][]*cp.MQTopicListeners {
	MQListenersTable := structMQListenInit(t, p)
	return map[cp.CheckMode][]*cp.MQTopicListeners{
		"struct": {
			MQListenersTable[StructIsBaseQuery],
			MQListenersTable[StructIsColumnMeta],
			MQListenersTable[StructIsIndexMeta],
			MQListenersTable[StructIsPartMeta],
			MQListenersTable[StructIsMetaComparison],
			MQListenersTable[StructIsFix],
			MQListenersTable[StructIsApply],
		},
	}
}
func objectMQListenInit(t, _ int) map[Topic]*cp.MQTopicListeners {
	return map[Topic]*cp.MQTopicListeners{
		ObjectBaseQuery:        cp.NewMQTopicListeners(cp.Topic(ObjectBaseQuery), t, singleQueryMessageQueueLength, objectBaseQueryListeners, 5, 11),
		ObjectIsJobMeta:        cp.NewMQTopicListeners(cp.Topic(ObjectIsJobMeta), t, singleQueryMessageQueueLength, objectIsJobMetaListeners, 5, 11),
		ObjectIsViewMeta:       cp.NewMQTopicListeners(cp.Topic(ObjectIsViewMeta), t, singleQueryMessageQueueLength, objectIsViewMetaListeners, 5, 11),
		ObjectIsProcedureMeta:  cp.NewMQTopicListeners(cp.Topic(ObjectIsProcedureMeta), t, singleQueryMessageQueueLength, objectIsProcedureMetaListeners, 5, 11),
		ObjectIsFuncMeta:       cp.NewMQTopicListeners(cp.Topic(ObjectIsFuncMeta), t, singleQueryMessageQueueLength, objectIsFuncMetaListeners, 5, 11),
		ObjectIsTriggerMeta:    cp.NewMQTopicListeners(cp.Topic(ObjectIsTriggerMeta), t, singleQueryMessageQueueLength, objectIsTriggerMetaListeners, 5, 11),
		ObjectIsPackageMeta:    cp.NewMQTopicListeners(cp.Topic(ObjectIsPackageMeta), t, singleQueryMessageQueueLength, objectIsPackageMetaListeners, 5, 11),
		ObjectIsTypeMeta:       cp.NewMQTopicListeners(cp.Topic(ObjectIsTypeMeta), t, singleQueryMessageQueueLength, objectIsTypeMetaListeners, 5, 11),
		ObjectIsForeignMeta:    cp.NewMQTopicListeners(cp.Topic(ObjectIsForeignMeta), t, singleQueryMessageQueueLength, objectIsForeignMetaListeners, 5, 11),
		ObjectIsSeqMeta:        cp.NewMQTopicListeners(cp.Topic(ObjectIsSeqMeta), t, singleQueryMessageQueueLength, objectIsSeqMetaListeners, 5, 11),
		ObjectIsMetaComparison: cp.NewMQTopicListeners(cp.Topic(ObjectIsMetaComparison), t, singleQueryMessageQueueLength, objectIsMetaComparisonListeners, 5, 11),
		ObjectIsFix:            cp.NewMQTopicListeners(cp.Topic(ObjectIsFix), t, singleQueryMessageQueueLength, objectIsFixListeners, 5, 11),
		ObjectIsApply:          cp.NewMQTopicListeners(cp.Topic(ObjectIsApply), t, singleQueryMessageQueueLength, objectIsApplyListeners, 5, 11),
	}
}
func objectMQListenInitFunc(t, p int) map[cp.CheckMode][]*cp.MQTopicListeners {
	MQListenersTable := objectMQListenInit(t, p)
	return map[cp.CheckMode][]*cp.MQTopicListeners{
		"object": {
			MQListenersTable[ObjectBaseQuery],
			MQListenersTable[ObjectIsTypeMeta],
			MQListenersTable[ObjectIsViewMeta],
			MQListenersTable[ObjectIsJobMeta],
			MQListenersTable[ObjectIsProcedureMeta],
			MQListenersTable[ObjectIsFuncMeta],
			MQListenersTable[ObjectIsTriggerMeta],
			MQListenersTable[ObjectIsPackageMeta],
			MQListenersTable[ObjectIsForeignMeta],
			MQListenersTable[ObjectIsSeqMeta],
			MQListenersTable[ObjectIsMetaComparison],
			MQListenersTable[ObjectIsFix],
			MQListenersTable[ObjectIsApply],
		},
	}
}

func topicCreateInit(checkMod string, t, p int) (m map[cp.CheckMode][]*cp.MQTopicListeners) {
	m = make(map[cp.CheckMode][]*cp.MQTopicListeners)
	if funcName, ok := MqListenerSInitFunc[checkMod]; ok {
		if funcName.Kind() == reflect.Func {
			m1 := funcName.Call([]reflect.Value{
				reflect.ValueOf(t),
				reflect.ValueOf(p),
			})
			for i := 0; i < len(m1); i++ {
				m = m1[i].Interface().(map[cp.CheckMode][]*cp.MQTopicListeners)
			}
		}
	}
	return m
}
func GetCheckToTopicMQListeners() map[cp.CheckMode][]*cp.MQTopicListeners {
	return topicCreateInit(GlobalPConfigs.rules.CheckMode, GlobalPConfigs.rules.Mtc, GlobalPConfigs.rules.Mcc)
}

func (context *SchedulePlanContext) topicEndAdd(index CheckMode, topic Topic) {
	context.AutoCloseMqComponentTable[cp.CheckMode(index)].TopicEndAdd(cp.Topic(topic))
}
func (context *SchedulePlanContext) topicEndMonit(index CheckMode, topic Topic) int64 {
	return context.AutoCloseMqComponentTable[cp.CheckMode(index)].TopicEndMonit(cp.Topic(topic))
}
func (context *SchedulePlanContext) topicEndDelete(index CheckMode, topic Topic) {
	context.AutoCloseMqComponentTable[cp.CheckMode(index)].TopicEndDelete(cp.Topic(topic))
}

func (context *SchedulePlanContext) topicEndDeleteNumber(index CheckMode, topic Topic, n int64) {
	context.AutoCloseMqComponentTable[cp.CheckMode(index)].TopicEndDeleteNumber(cp.Topic(topic), n)
}

func sendMsg(check CheckMode, topic Topic, tableName string, msg map[string]any) bool {
	var outFay string
	PlanContext.topicEndAdd(check, topic)
	if err := producer.Send(mq.Message{
		Topic:      string(topic),
		Body:       []byte(tableName),
		Properties: msg,
	}); err != nil {
		return false
	}
	if v, ok := msg["outFay"]; ok {
		outFay = v.(string)
	}
	if strings.EqualFold(outFay, "bar") {
		PlanContext.taskBarEndTopicAdd(msg)
	}
	return true
}
func deleteTopic(topicMsg map[string]any) {
	var (
		dTopic Topic
		outFay = "bar"
	)
	if v, ok := topicMsg["topic"]; ok {
		dTopic = v.(Topic)
	}
	if v, ok := topicMsg["outFay"]; ok {
		outFay = v.(string)
	}
	PlanContext.topicEndDelete(getCheckMod(), dTopic)
	if strings.EqualFold(outFay, "bar") {
		PlanContext.TaskBarEndTopicDel(topicMsg)
	}
}
